package su.msk.jet.team01.chatik.client;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import su.msk.jet.team01.chatik.client.ui.UserInterface;
import su.msk.jet.team01.chatik.client.ui.swing.ChatForm;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class ClientApplication {

	private static Logger logger = LoggerFactory.getLogger(ClientApplication.class);

	private Socket socket = null;
	private ObjectInputStream in = null;
	private ObjectOutputStream out = null;
	private UserInterface ui;

	public ClientApplication() {
		ui = new ChatForm();
		UIInputHandler messageSender;

		messageSender = new UIInputHandler(this, ui);

		messageSender.start();
	}

	public synchronized void connect(final String host, final int port) {

		UIOutputHandler messageReceiver;

		if (connected()) {
			ui.printMessage("You are already connected");
			return;
		}

		ui.printMessage("Connecting to " + host + ":" + port + "...");
		try {
			socket = new Socket(host, port);
			out = new ObjectOutputStream(socket.getOutputStream());
			out.flush();
			in = new ObjectInputStream(socket.getInputStream());

			messageReceiver = new UIOutputHandler(this, ui);
			messageReceiver.start();

			ui.printMessage("Connection successful");
		} catch (IllegalArgumentException ex) {
			ui.printMessage("Port out of range");
			logger.error(ex.getMessage(), ex);
		} catch (UnknownHostException ex) {
			ui.printMessage("Unknown host");
			logger.error(ex.getMessage(), ex);
		} catch (IOException ex) {
			ui.printMessage("Host unreachable");
			logger.error(ex.getMessage(), ex);
			socket = null;
		}
	}

	public boolean connected() {
		return socket != null;
	}

	public ObjectInputStream input() {
		return in;
	}

	public ObjectOutputStream output() {
		return out;
	}

	public synchronized void close() {
		if (socket != null) {
			try {
				in.close();
				out.close();
				socket.close();
			} catch (IOException ex) {
				logger.error("Unable to close connection.", ex);
			}
			socket = null;
			in = null;
			out = null;
			ui.printMessage("Disconnected from the server");
		}
	}

	public static void main(String[] args) {
		new ClientApplication();
	}

}
